#include <algorithm>
#include <iostream>
#include <cmath>
#include <numeric>

using namespace std;

namespace ops {
/**
 * if y is 0, return x
 */
template <typename T>
typename std::enable_if <std::is_signed<T>::value, T>::type CeilDiv(T x, T y) {
  if (y != 0 && x != 0) {
    const T quotient = x / y;
    return (x % y != 0 && ((x ^ y) >= 0)) ? (quotient + 1) : quotient;
  }

  return x;
}

/**
 * if y is 0, return x
 */
template <typename T>
typename std::enable_if <std::is_unsigned<T>::value, T>::type CeilDiv(T x, T y) {
  if (y != 0 && x != 0) {
    const T quotient = x / y;
    return (x % y != 0) ? (quotient + 1) : quotient;
  }

  return x;
}

template <typename T1, typename T2>
inline T1 CeilDiv(T1 a, T2 b) {
    return (a + b - 1) / b;
}
template <typename T1, typename T2>
inline T1 FloorDiv(T1 a, T2 b) {
    return (a) / (b);
}
template <typename T1, typename T2>
inline T1 CeilAlign(T1 a, T2 b) {
    return (a + b - 1) / b * b;
}
template <typename T1, typename T2>
inline T1 FloorAlign(T1 a, T2 b) {
    return (a) / b * b;
}
}

constexpr int64_t BYTES_PER_BLOCK = 32;
constexpr int64_t BLOCKS_PER_VECTOR_BYTE = 8;
constexpr int64_t TILING_NO_SCALING = 0;
constexpr int64_t TILING_ONE_2_MANY = 1;
constexpr int64_t TILING_MANY_2_ONE = 2;
constexpr int64_t TILING_SMALL_W = 3;
constexpr int64_t TILING_DEFAULT = 4;
constexpr int64_t POS_NC = 0;
constexpr int64_t POS_HW = 1;
constexpr int64_t MIN_BLOCK_NUM = 8;
constexpr int64_t VDP_LEN = 4096;
constexpr int64_t INDEX_DATA_SIZE = 4;
constexpr int64_t INDEX_PER_BLOCK = BYTES_PER_BLOCK / INDEX_DATA_SIZE;
constexpr int64_t RESERVED_UB_SIZE = 8 * 1024;
constexpr int64_t RESERVED_UB_IDX_BASE_LEN = 64;
constexpr int64_t UB_IDX_SIZE = RESERVED_UB_SIZE / INDEX_DATA_SIZE - RESERVED_UB_IDX_BASE_LEN;

struct ResizeNB2DCompileInfo {
  int64_t coreNum = 1;
  int64_t ubMaxNum = 1;
  bool alignCorners = false;
  bool halfPixelCenters = false;
  int64_t resizeMode = 0;
};

struct ResizeNB2DInfoR {
  int64_t tilingKey = 0;
  int64_t subKey = 0;
  int64_t ubOffset = 0;
  int64_t usedCoreCnt = 1;
  int64_t mcPos = 0;
  int64_t coreInOffset = 0;
  int64_t coreOutOffset = 0;
  int64_t ncLoopUnit = 1;
  int64_t hLoopUnit = 1;
  int64_t wLoopUnit = 1;
  int64_t ncPerCore = 1;
  int64_t hPerCore = 1;
  int64_t wPerCore = 1;
  int64_t ncSize = 1;
  int64_t inHSize = 1;
  int64_t inWSize = 1;
  int64_t outHSize = 1;
  int64_t outWSize = 1;
  int64_t inSize = 1;
  int64_t outSize = 1;
  int64_t ubOffset2 = 0;
  int64_t inWAlign = 1;
  int64_t outWAlign = 1;
};

static std::string PrintTilingData(const ResizeNB2DInfoR* tilingDataPtr) {
  std::string tilingStr;

  tilingStr += std::to_string(tilingDataPtr->tilingKey) + ",";
  tilingStr += std::to_string(tilingDataPtr->subKey) + ",";
  tilingStr += std::to_string(tilingDataPtr->ubOffset) + ",";
  tilingStr += std::to_string(tilingDataPtr->usedCoreCnt) + ",";
  tilingStr += std::to_string(tilingDataPtr->mcPos) + ",";
  tilingStr += std::to_string(tilingDataPtr->coreInOffset) + ",";
  tilingStr += std::to_string(tilingDataPtr->coreOutOffset) + ",";
  tilingStr += std::to_string(tilingDataPtr->ncLoopUnit) + ",";
  tilingStr += std::to_string(tilingDataPtr->hLoopUnit) + ",";
  tilingStr += std::to_string(tilingDataPtr->wLoopUnit) + ",";
  tilingStr += std::to_string(tilingDataPtr->ncPerCore) + ",";
  tilingStr += std::to_string(tilingDataPtr->hPerCore) + ",";
  tilingStr += std::to_string(tilingDataPtr->wPerCore) + ",";
  tilingStr += std::to_string(tilingDataPtr->ncSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->inHSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->inWSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->outHSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->outWSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->inSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->outSize) + ",";
  tilingStr += std::to_string(tilingDataPtr->ubOffset2) + ",";
  tilingStr += std::to_string(tilingDataPtr->inWAlign) + ",";
  tilingStr += std::to_string(tilingDataPtr->outWAlign);

  return tilingStr;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static bool SetMCTiling4NoScaling(const ResizeNB2DCompileInfo* compileInfo, const int64_t elePerBlock,
                                  ResizeNB2DInfoR* tilingDataPtr) {
  int64_t minLoopUnit = MIN_BLOCK_NUM * elePerBlock;
  int64_t nchwSize = tilingDataPtr->ncSize * tilingDataPtr->inWSize * tilingDataPtr->inHSize;
  int64_t coreNum = compileInfo->coreNum;

  // to make sure the elements in per core is block align or all
  tilingDataPtr->coreInOffset = std::min(ops::CeilAlign(ops::CeilDiv(nchwSize, coreNum), minLoopUnit), nchwSize);
  tilingDataPtr->usedCoreCnt = ops::CeilDiv(nchwSize, tilingDataPtr->coreInOffset);
  tilingDataPtr->coreOutOffset = tilingDataPtr->coreInOffset;
  tilingDataPtr->wLoopUnit = compileInfo->ubMaxNum;
  tilingDataPtr->inWSize = nchwSize;

  return true;
}

static bool SetMCTiling4One2Many(const ResizeNB2DCompileInfo* compileInfo, const int64_t elePerBlock,
                                 ResizeNB2DInfoR* tilingDataPtr) {
  int64_t minWLoopUnit = 32;
  int64_t minNCLoopUnit = 2 * elePerBlock;

  tilingDataPtr->outWSize = tilingDataPtr->outHSize * tilingDataPtr->outWSize;
  tilingDataPtr->outHSize = 1;
  tilingDataPtr->ubOffset = compileInfo->ubMaxNum / 2 / elePerBlock * elePerBlock;

  if (tilingDataPtr->ncSize < tilingDataPtr->outWSize / minWLoopUnit) {
    tilingDataPtr->mcPos = POS_HW;
    tilingDataPtr->subKey = 0;
    tilingDataPtr->ncPerCore = tilingDataPtr->ncSize;
    tilingDataPtr->ncLoopUnit = tilingDataPtr->ubOffset;
    tilingDataPtr->coreInOffset = 0;
    tilingDataPtr->coreOutOffset =
        std::min(ops::CeilAlign(ops::CeilDiv(tilingDataPtr->outWSize, compileInfo->coreNum), minWLoopUnit),
                 tilingDataPtr->outWSize);
    tilingDataPtr->usedCoreCnt = ops::CeilDiv(tilingDataPtr->outWSize, tilingDataPtr->coreOutOffset);
    tilingDataPtr->wPerCore = tilingDataPtr->coreOutOffset;
    tilingDataPtr->wLoopUnit = VDP_LEN;
  } else {
    // to keep nc per core is block align or all
    if (tilingDataPtr->outWSize <= minWLoopUnit) {
      tilingDataPtr->subKey = 1;
      tilingDataPtr->coreInOffset =
          std::min(ops::CeilAlign(ops::CeilDiv(tilingDataPtr->ncSize, compileInfo->coreNum), minNCLoopUnit),
                   tilingDataPtr->ncSize);
      tilingDataPtr->wLoopUnit = minWLoopUnit;
      tilingDataPtr->ncLoopUnit = tilingDataPtr->ubOffset / tilingDataPtr->outWSize / elePerBlock * elePerBlock;
    } else {
      tilingDataPtr->subKey = 0;
      tilingDataPtr->coreInOffset =
          std::min(ops::CeilDiv(tilingDataPtr->ncSize, compileInfo->coreNum), tilingDataPtr->ncSize);
      tilingDataPtr->wLoopUnit = VDP_LEN;
      tilingDataPtr->ncLoopUnit = tilingDataPtr->ubOffset;
    }
    tilingDataPtr->mcPos = POS_NC;
    tilingDataPtr->wPerCore = tilingDataPtr->outWSize;
    tilingDataPtr->coreOutOffset = tilingDataPtr->coreInOffset * tilingDataPtr->outWSize;
    tilingDataPtr->ncPerCore = tilingDataPtr->coreInOffset;
    tilingDataPtr->usedCoreCnt = ops::CeilDiv(tilingDataPtr->ncSize, tilingDataPtr->coreInOffset);
  }

  return true;
}

static bool SetMCTiling4Many2One(const ResizeNB2DCompileInfo* compileInfo, const int64_t elePerBlock,
                                 ResizeNB2DInfoR* tilingDataPtr) {
  int64_t hwSize = tilingDataPtr->inHSize * tilingDataPtr->inWSize;
  int64_t vgatherGate = MIN_BLOCK_NUM * elePerBlock;

  tilingDataPtr->ubOffset = compileInfo->ubMaxNum / 2 / elePerBlock * elePerBlock;
  if (hwSize <= vgatherGate) {
    tilingDataPtr->subKey = 0;
    tilingDataPtr->ncLoopUnit = tilingDataPtr->ubOffset / hwSize / elePerBlock * elePerBlock;
  } else {
    tilingDataPtr->subKey = 1;
    tilingDataPtr->ncLoopUnit = tilingDataPtr->ubOffset / elePerBlock / elePerBlock * elePerBlock;
  }
  tilingDataPtr->ncPerCore = std::min(
      ops::CeilAlign(ops::CeilDiv(tilingDataPtr->ncSize, compileInfo->coreNum), elePerBlock), tilingDataPtr->ncSize);
  tilingDataPtr->usedCoreCnt = ops::CeilDiv(tilingDataPtr->ncSize, tilingDataPtr->ncPerCore);
  tilingDataPtr->coreOutOffset = tilingDataPtr->ncPerCore;
  tilingDataPtr->coreInOffset = tilingDataPtr->coreOutOffset * hwSize;

  return true;
}

static void SetTilingCoreParam4SplitNC(ResizeNB2DInfoR* tilingDataPtr, int64_t coreNum) {
  tilingDataPtr->ncPerCore = ops::CeilDiv(tilingDataPtr->ncSize, coreNum);
  tilingDataPtr->usedCoreCnt = ops::CeilDiv(tilingDataPtr->ncSize, tilingDataPtr->ncPerCore);
  tilingDataPtr->inSize = tilingDataPtr->inHSize * tilingDataPtr->inWSize;
  tilingDataPtr->outSize = tilingDataPtr->outHSize * tilingDataPtr->outWSize;
  tilingDataPtr->coreInOffset = tilingDataPtr->ncPerCore * tilingDataPtr->inSize;
  tilingDataPtr->coreOutOffset = tilingDataPtr->ncPerCore * tilingDataPtr->outSize;
}

static bool SetMCTiling4SmallW(const ResizeNB2DCompileInfo* compileInfo, const int64_t elePerBlock,
                               ResizeNB2DInfoR* tilingDataPtr) {
  SetTilingCoreParam4SplitNC(tilingDataPtr, compileInfo->coreNum);

  tilingDataPtr->hLoopUnit = UB_IDX_SIZE - tilingDataPtr->outWAlign * INDEX_DATA_SIZE;

  tilingDataPtr->outWAlign = ops::CeilAlign(tilingDataPtr->outWSize, elePerBlock);
  const int64_t inSizeAlign = ops::CeilAlign(tilingDataPtr->inSize, elePerBlock);
  tilingDataPtr->ncLoopUnit = std::min(ops::FloorDiv(compileInfo->ubMaxNum,
                                                     inSizeAlign + tilingDataPtr->outWAlign * tilingDataPtr->outHSize),
                                       tilingDataPtr->ncPerCore);
  if (tilingDataPtr->ncLoopUnit == 0) {
     // 先不考虑需要分H轴的情况，这里没写完
    tilingDataPtr->mcPos = POS_HW;
    tilingDataPtr->ncLoopUnit = 1;
  } else {
    tilingDataPtr->mcPos = POS_NC;
    tilingDataPtr->ubOffset = inSizeAlign * tilingDataPtr->ncLoopUnit;
  }

  return true;
}

static bool SetMCTiling4Default(const ResizeNB2DCompileInfo* compileInfo, const int64_t elePerBlock,
                                ResizeNB2DInfoR* tilingDataPtr) {
  SetTilingCoreParam4SplitNC(tilingDataPtr, compileInfo->coreNum);

  constexpr int64_t W_SUBKEY_FACTOR = 10;
  constexpr int64_t H_SUBKEY_FACTOR = 100;
  constexpr int64_t SUBKEY_EQUAL = 1;
  constexpr int64_t SUBKEY_ONE_2_MANY = 2;
  constexpr int64_t SUBKEY_MANY_2_ONE = 3;
  constexpr int64_t SUBKEY_INT_SCALE_ZOOM_OUT = 4;
  constexpr int64_t SUBKEY_INT_SCALE_ZOOM_IN = 5;
  if (tilingDataPtr->inWSize == tilingDataPtr->outWSize) {
    tilingDataPtr->subKey += W_SUBKEY_FACTOR * SUBKEY_EQUAL;
  } else if (tilingDataPtr->inWSize == 1) {
    tilingDataPtr->subKey += W_SUBKEY_FACTOR * SUBKEY_ONE_2_MANY;
  } else if (tilingDataPtr->outWSize == 1) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_MANY_2_ONE;
  } else if (tilingDataPtr->outWSize > tilingDataPtr->inWSize && tilingDataPtr->outWSize % tilingDataPtr->inWSize == 0) {
    tilingDataPtr->subKey += W_SUBKEY_FACTOR * SUBKEY_INT_SCALE_ZOOM_OUT;
  } else if (tilingDataPtr->inWSize > tilingDataPtr->outWSize && tilingDataPtr->inWSize % tilingDataPtr->outWSize == 0) {
    tilingDataPtr->subKey += W_SUBKEY_FACTOR * SUBKEY_INT_SCALE_ZOOM_IN;
  }
  if (tilingDataPtr->inHSize == tilingDataPtr->outHSize) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_EQUAL;
  } else if (tilingDataPtr->inHSize == 1) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_ONE_2_MANY;
  } else if (tilingDataPtr->outHSize == 1) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_MANY_2_ONE;
  } else if (tilingDataPtr->outHSize > tilingDataPtr->inHSize && tilingDataPtr->outHSize % tilingDataPtr->inHSize == 0) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_INT_SCALE_ZOOM_OUT;
  } else if (tilingDataPtr->inHSize > tilingDataPtr->outHSize && tilingDataPtr->inHSize % tilingDataPtr->outHSize == 0) {
    tilingDataPtr->subKey += H_SUBKEY_FACTOR * SUBKEY_INT_SCALE_ZOOM_IN;
  }

  tilingDataPtr->hLoopUnit = UB_IDX_SIZE;

  const int64_t eleSize = BYTES_PER_BLOCK / elePerBlock;
  const int64_t ubSize = compileInfo->ubMaxNum * eleSize;
  tilingDataPtr->inWAlign = ops::CeilAlign(tilingDataPtr->inWSize, elePerBlock);
  tilingDataPtr->outWAlign = ops::CeilAlign(tilingDataPtr->outWSize, elePerBlock);
  const int64_t inWUbSize = tilingDataPtr->inWAlign * eleSize;
  const int64_t outWUbSize = tilingDataPtr->outWAlign * eleSize;
  const int64_t outWUbIdxSize = tilingDataPtr->outWAlign * INDEX_DATA_SIZE;
  if (ubSize >= inWUbSize + outWUbSize + outWUbIdxSize) {
    tilingDataPtr->mcPos = POS_NC;
    tilingDataPtr->wLoopUnit = tilingDataPtr->outWSize;
    tilingDataPtr->ncLoopUnit = ops::FloorDiv(ubSize - outWUbIdxSize,
                                              (tilingDataPtr->inWAlign + tilingDataPtr->outWAlign) * eleSize);
  } else { // 先不不考虑W过大的情况，有可能用别的模板
    tilingDataPtr->mcPos = POS_HW;
    tilingDataPtr->ncLoopUnit = 1;
  }
  tilingDataPtr->ubOffset = tilingDataPtr->ncLoopUnit * tilingDataPtr->inWAlign;
  tilingDataPtr->ubOffset2 = tilingDataPtr->ubOffset + tilingDataPtr->ncLoopUnit * tilingDataPtr->outWAlign;

  return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main() {
    int64_t inN;
    int64_t inC;
    int64_t inH;
    int64_t inW;
    int64_t sizeH;
    int64_t sizeW;
    int64_t dtype_size;
    bool alignCorners;
    bool halfPixelCenters;
    int64_t tilingKey;
    cin >> inN >> inC >> inH >> inW >> sizeH >> sizeW >> dtype_size >> alignCorners >> halfPixelCenters >> tilingKey;
    const int64_t elePerBlock = BYTES_PER_BLOCK / dtype_size;
    ResizeNB2DCompileInfo compileInfo {
        .coreNum = 48,
        .ubMaxNum = 188416 / dtype_size,
        .alignCorners = alignCorners,
        .halfPixelCenters = halfPixelCenters,
        .resizeMode = 0,
    };
    ResizeNB2DInfoR tilingDataPtr {
        .tilingKey = tilingKey,
        .subKey = 0,
        .ubOffset = 0,
        .usedCoreCnt = 1,
        .mcPos = 0,
        .coreInOffset = 0,
        .coreOutOffset = 0,
        .ncLoopUnit = 1,
        .hLoopUnit = 1,
        .wLoopUnit = 1,
        .ncPerCore = 1,
        .hPerCore = 1,
        .wPerCore = 1,
        .ncSize = inN * inC,
        .inHSize = inH,
        .inWSize = inW,
        .outHSize = sizeH,
        .outWSize = sizeW,
        .inSize = 1,
        .outSize = 1,
        .ubOffset2 = 0,
        .inWAlign = 1,
        .outWAlign = 1,
    };
    switch (tilingKey) {
      case TILING_NO_SCALING:
        SetMCTiling4NoScaling(&compileInfo, elePerBlock, &tilingDataPtr);
      break;
      case TILING_ONE_2_MANY:
        SetMCTiling4One2Many(&compileInfo, elePerBlock, &tilingDataPtr);
      break;
      case TILING_MANY_2_ONE:
        SetMCTiling4Many2One(&compileInfo, elePerBlock, &tilingDataPtr);
      break;
      case TILING_SMALL_W:
        SetMCTiling4SmallW(&compileInfo, elePerBlock, &tilingDataPtr);
      break;
      default:
        SetMCTiling4Default(&compileInfo, elePerBlock, &tilingDataPtr);
      break;
    }
    cout << '[' << PrintTilingData(&tilingDataPtr) << ']' << endl;
}